package com.astruyk.battlegroundAndroid.data;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.FactoryConfigurationError;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;

import com.astruyk.battlegroundAndroid.R;

/**
 * Updates the contents of the database based on the live information pulled from Wiretap
 * 
 * @author Anton Struyk
 *
 */
public class TownUpdater {
	/**
	 * Singleton instance of this class.
	 */
	public static final TownUpdater instance = new TownUpdater();
	
	private TownUpdater() {
		//Private constructor to prevent user instantiation of singleton
	}
	
	private final Handler handler = new Handler();
	private ProgressDialog progressDialog;
	
	public interface AsyncResult
	{
		/*
		 * A function that will be run when the asynchronous operation is complete
		 */
		public void operationComplete();
	}
	
	public void refreshTownList(Context context, AsyncResult result){
		progressDialog = ProgressDialog.show(context, "Working", "Refreshing XML", true, false);
		Thread t = new Thread(new RefreshTownRunnable(context, result));
		t.start();
	}
	
	private class RefreshTownRunnable implements Runnable
	{
		public RefreshTownRunnable(Context context, AsyncResult result){
			this.context = context;
			this.result = result;
		}
		
		private Context context;
		private AsyncResult result;

		@Override
		public void run() {
			URL url;
			try {
				String townFeed = context.getString(R.string.cp_states_url);
				url = new URL(townFeed);
				
				URLConnection connection;
				connection  = url.openConnection();
				
				HttpURLConnection httpConnection = (HttpURLConnection)connection;
				int responseCode = httpConnection.getResponseCode();
				
				if(responseCode == HttpURLConnection.HTTP_OK){
					InputStream in = httpConnection.getInputStream();
					
					XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
					final XmlPullParser pullParser = factory.newPullParser();
					
					pullParser.setInput(in, null);
					int eventType = pullParser.getEventType();
					while(eventType != XmlPullParser.END_DOCUMENT){
						if(eventType == XmlPullParser.START_TAG){
							String currentTag = pullParser.getName();
							
							if(currentTag.equalsIgnoreCase("cp")){
								//Update the progress dialog
								handler.post(new Runnable(){
									@Override
									public void run() {
										progressDialog.setMessage("Parsing Line " + pullParser.getLineNumber());									}
								});
								
								//Get the current CP values from the XML
								int id = getAttributeValueAsInt(pullParser, "id");
								int owner = getAttributeValueAsInt(pullParser, "owner");
								
								//Create a contentValues to update the data provider with
								ContentValues values = new ContentValues();
								values.put(CapturePoint.ORIG_COUNTRY, owner);
								
								//Append the data to the dataProvider
								Uri cpUri = Uri.withAppendedPath(CapturePoint.CONTENT_URI, String.valueOf(id));
								context.getContentResolver().update(cpUri, values, null, null);
							}
						}
						eventType = pullParser.next();
					}
				}
			} catch (NumberFormatException e) {
				e.printStackTrace();
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (FactoryConfigurationError e) {
				e.printStackTrace();
			} catch (XmlPullParserException e) {
				e.printStackTrace();
			}
			
			handler.post(new Runnable(){
				public void run() {
					progressDialog.dismiss();
					result.operationComplete();
				}
			});
		}
	}

	private static int getAttributeValueAsInt(XmlPullParser parser, String attributeName){
		String value = parser.getAttributeValue(null, attributeName);
		try{
			return Integer.parseInt(value);
		}catch(NumberFormatException e){
			Log.e("TownList", "Unable to convert '" + value + "' to number for attribute '" + attributeName + "'");
			return -1;
		}
	}
}
